﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Common.Model;
using System.Data.Objects.DataClasses;
using Common.Services;
using System.ComponentModel;
using System.Windows;

namespace Common.UI.Controls
{
    public class GenericDropDownList<S, E> : ComboBox, ISubscriberControl
        where S : IGenericEntityReaderService<E>, new()
        where E : EntityObject
    {

        public E Value
        {
            get { return (E)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(E), typeof(GenericDropDownList<S, E>), new UIPropertyMetadata(null, new PropertyChangedCallback(Value_Changed)));

        private static void Value_Changed(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            GenericDropDownList<S, E> control = (GenericDropDownList<S, E>)o;

            control.LoadExistingValue(e.NewValue as E);
        }

        /// <summary>
        /// Indica si el control en algun momento se cargo.
        /// </summary>
        private Boolean isLoaded = false;

        IGenericEntityReaderService<E> _entityReader;
        public IGenericEntityReaderService<E> EntityReader
        {
            get
            {
                if (_entityReader == null)
                {
                    _entityReader = new S();
                }
                return _entityReader;
            }
        }

        /// <summary>
        /// Indica si refrezca la lista cuando el control es cargado
        /// </summary>
        public Boolean RefreshWhenLoaded
        {
            get;
            set;
        }

        /// <summary>
        /// Permite especificarle cual es la propiedad que se utiliza para mostrar el item.
        /// </summary>
        public virtual String DisplayMemberPropertyName
        {
            get { return "Descripcion"; }
        }

        public GenericDropDownList()
            : base()
        {
            this.Loaded += new System.Windows.RoutedEventHandler(GenericDropDownList_Loaded);
            this.Initialized += new EventHandler(GenericDropDownList_Initialized);

            this.SelectionChanged +=new SelectionChangedEventHandler(GenericDropDownList_SelectionChanged);
        }

        private static void SelectedItem_Changed(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
        }

        void GenericDropDownList_Initialized(object sender, EventArgs e)
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this.LoadEntities();
                isLoaded = true;
            }
        }

        void GenericDropDownList_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            if (isLoaded && RefreshWhenLoaded)
            {
                this.LoadEntities();
            }
        }

        private void LoadExistingValue(E newEntity)
        {
            if (newEntity != null)
            {
                var lista = this.ItemsSource as List<E>;
                if (!lista.Contains(newEntity))
                {
                    lista.Add(newEntity);
                    this.ItemsSource = lista;
                }
                this.SelectedItem = newEntity;
            }
        }

        private void LoadEntities()
        {
            this.ItemsSource = EntityReader.ReadEntities();
            this.DisplayMemberPath = this.DisplayMemberPropertyName;
        }

        #region Subscription

        List<ISubscriberControl> _relatedControls = new List<ISubscriberControl>();
        public List<ISubscriberControl> RelatedControls
        {
            get { return _relatedControls; }
            set { _relatedControls = value; }
        }

        public void AddSubscriber(ISubscriberControl control)
        {
            RelatedControls.Add(control);
        }

        void GenericDropDownList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count != 0)
            {
                foreach (var control in RelatedControls)
                {
                    control.SubscriberChanged(e.AddedItems[0] as EntityObject);
                }
            }
        }

        public void SubscriberChanged(EntityObject entityObject)
        {
            this.LoadEntitiesByParameter(entityObject);
        }

        private void LoadEntitiesByParameter(EntityObject entityObject)
        {
            this.ItemsSource = EntityReader.ReadEntitiesByParameter(entityObject);
            this.DisplayMemberPath = this.DisplayMemberPropertyName;
        }

        #endregion

    }
}